#include "ClassFeatureProxyModel.h"



#include <Item.h>



#include <QDebug>



namespace
{

QStringList EXCLUDE_GROUP_IDS = QStringList()
                                << ".Skill"
                                << ".Feat"
                                //<< ".Class Features"
                                << ".Knowledge"
                                << ".Craft"
                                << ".Profession"
                                << ".Perform";
}



ClassFeatureProxyModel::ClassFeatureProxyModel(QObject *parent) :
    AbstractTreeProxyModel(parent)
{
}



int ClassFeatureProxyModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);

    return (Field_LAST - Field_FIRST + 1);
}



QVariant ClassFeatureProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_UNUSED(orientation);
    if (role != Qt::DisplayRole) return QVariant();

    switch (section)
    {
    case NameField: return tr("Character Features");
    case ValueField: return tr("Value");
    }

    return QVariant();
}



Qt::ItemFlags ClassFeatureProxyModel::flags(const QModelIndex &proxyModel) const
{
    if (!proxyModel.isValid()) return Qt::NoItemFlags;

    QModelIndex sourceModel = mapToSource(proxyModel);
    if (!sourceModel.isValid()) return Qt::NoItemFlags;

    if (sourceModel.parent().isValid()) return Qt::ItemIsEditable | Qt::ItemIsEnabled;

    if (proxyModel.column() == NameField) return Qt::ItemIsEditable | Qt::ItemIsEnabled;

    return Qt::ItemIsEnabled;
}



void ClassFeatureProxyModel::remap()
{
    ItemModel* model = itemModel();
    if (!model) return;

    QModelIndex groupName = model->index(0,AbstractItem::NameData, QModelIndex());
    while (groupName.isValid())
    {
        QModelIndex groupId = groupName.sibling(groupName.row(), AbstractItem::IdData);
        if (!groupId.isValid())
        {
            groupName = groupName.sibling(groupName.row()+1, groupName.column());
            continue;
        }

        //qDebug() << Q_FUNC_INFO << "- maaping group" << groupId.data(Qt::EditRole).toString();

        bool exclude = false;
        foreach (QString excludeId, EXCLUDE_GROUP_IDS)
        {
            if (!groupId.data(Qt::EditRole).toString().contains(excludeId)) continue;

            exclude = true;
            break;
        }

        if (exclude)
        {
            //qDebug() << "excluded group";
            groupName = groupName.sibling(groupName.row()+1, groupName.column());
            continue;
        }


        mapIndex(NameField, groupName);
        mapIndex(ValueField, groupId);

        QModelIndex itemName = groupName.child(0, AbstractItem::NameData);
        while (itemName.isValid())
        {
            QModelIndex itemValue = itemName.sibling(itemName.row(), Item::ValueData);
            if (itemValue.isValid())
            {
                mapIndex(NameField, itemName);
                mapIndex(ValueField, itemValue);
            }

            itemName = itemName.sibling(itemName.row()+1, itemName.column());
        }

        groupName = groupName.sibling(groupName.row()+1, groupName.column());
    }

}



void ClassFeatureProxyModel::mapIndex(const int &field, const QModelIndex &sourceIndex)
{
    QModelIndex categorySource = sourceIndex.sibling(sourceIndex.row(), AbstractItem::CategoryData);
    if (!categorySource.isValid()) return;


    switch (categorySource.data(Qt::EditRole).toInt())
    {
    case ItemCategory_Group:
        {
            //qDebug() << "Mapping group:" << sourceIndex.data(Qt::EditRole).toString();
            int rows = rowCount(QModelIndex());
            addMapping(sourceIndex, createIndex(rows, field, sourceIndex.internalPointer()));
            return;
        }

    case ItemCategory_Item:
        break;

    default:
        return;
    }

    QModelIndex parentSource = sourceIndex.parent();
    if (!parentSource.isValid()) return;

    QModelIndex parentNameSource = parentSource.sibling(parentSource.row(), AbstractItem::NameData);
    ProxyIndex parentNameProxy = mapFromSource(parentNameSource);
    if (!parentNameProxy.isValid()) return;

    addChildMapping(parentNameProxy, sourceIndex, createIndex(sourceIndex.row(), field, sourceIndex.internalPointer()));
}



